/*
 * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved.
 *
 * OpenArkCompiler is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
 * FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#include "ipa_side_effect.h"
#include "func_desc.h"
namespace maple {
const std::map<std::string, FuncDesc> whiteList = {
#include "func_desc.def"
};

const FuncDesc &SideEffect::GetFuncDesc(MeFunction &f) {
  return SideEffect::GetFuncDesc(*f.GetMirFunc());
}

const FuncDesc &SideEffect::GetFuncDesc(MIRFunction &f) {
  auto it = whiteList.find(f.GetName());
  if (it != whiteList.end()) {
    return it->second;
  }
  return f.GetFuncDesc();
}

const std::map<std::string, FuncDesc> &SideEffect::GetWhiteList() {
  return whiteList;
}

bool SideEffect::Perform(MeFunction &f) {
  (void)f;
  (void)alias;
  (void)meFunc;
  (void)dom;
  return false;
}

bool SCCSideEffect::PhaseRun(SCCNode &scc) {
  bool changed = true;
  while (changed) {
    changed = false;
    auto *map = GET_ANALYSIS(SCCPrepare, scc);
    for (CGNode *node : scc.GetCGNodes()) {
      MIRFunction *func = node->GetMIRFunction();
      if (func != nullptr) {
        if (func->IsEmpty()) {
          continue;
        }
        MeFunction *meFunc = func->GetMeFunc();
        auto *phase = map->GetVaildAnalysisPhase(meFunc->GetUniqueID(), &MEDominance::id);
        Dominance *dom = static_cast<MEDominance*>(phase)->GetResult();
        phase = map->GetVaildAnalysisPhase(meFunc->GetUniqueID(), &MEAliasClass::id);
        AliasClass *alias = static_cast<MEAliasClass*>(phase)->GetResult();

        phase = map->GetVaildAnalysisPhase(meFunc->GetUniqueID(), &MESSATab::id);
        SSATab *meSSATab = static_cast<MESSATab*>(phase)->GetResult();
        CHECK_FATAL(meSSATab == meFunc->GetMeSSATab(), "IPA_PM may be wrong.");
        SideEffect *se = GetPhaseMemPool()->New<SideEffect>(meFunc, dom, alias);
        changed |= se->Perform(*meFunc);
      }
    }
  }
  return false;
}

void SCCSideEffect::GetAnalysisDependence(maple::AnalysisDep &aDep) const {
  aDep.AddRequired<SCCPrepare>();
}
}  // namespace maple
